package com.cn.ZhiKeDianShang.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.cn.ZhiKeDianShang.base.GlobalApp;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2018/3/7 0007.
 */

public class AndroidUtil {

    public static final String TAG = "AndroidUtil";
    public static final String NET_WIFI = "WIFI";
    public static final String NET_4G = "4G";
    public static final String NET_3G = "3G";
    public static final String NET_2G = "2G";
    public static final String NET_UNKNOWN = "UNKNOWN";
//
//    /**
//     * 获取手机唯一序列号
//     * 注：如取不到设备号，则取UUID作为手机唯一序列号
//     */
//    public static String getDeviceUUID(Context context) {
//        return Installation.id(context);
//    }

    /**
     * 获取手机序列号
     */
    @SuppressLint("MissingPermission")
    public static String getDeviceId(Context context) {
        String deviceID = null;

        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (!TextUtils.isEmpty(tm.getDeviceId())) {
            deviceID = tm.getDeviceId();
        }

        return deviceID;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 说明：根据手机的分辨率将sp转成为px
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 获取应用的ApplicationId
     *
     * @param context
     * @return
     */
    public static String getApplicationId(Context context) {
        try {
            String pkName = context.getPackageName();
            return pkName;
        } catch (Exception e) {
        }
        return null;
    }


    /**
     * 获取应用版本号
     */
    public static String getAppVersion(Context context) {
        String strVersion = null;

        try {
            PackageInfo pi = null;
            pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            if (pi != null) {
                strVersion = pi.versionName;
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, e.getMessage(), e);
        }

        return strVersion;
    }

    /**
     * 获取签名摘要
     */
    public static String getSign(Context context) {
        String strSign = null;

        try {
            int flag = PackageManager.GET_SIGNATURES;
            PackageManager pm = context.getPackageManager();
            List<PackageInfo> apps = pm.getInstalledPackages(flag);
            Object[] objs = apps.toArray();
            for (int i = 0, j = objs.length; i < j; i++) {
                PackageInfo packageinfo = (PackageInfo) objs[i];
                String packageName = packageinfo.packageName;
                if (packageName.equals(context.getPackageName())) {
                    Signature[] temps = packageinfo.signatures;
                    Signature tmpSign = temps[0];
                    strSign = tmpSign.toCharsString();
                }
            }
        } catch (Exception e) {
        }
        return strSign;
    }

    /**
     * 判断手机是否ROOT
     */
    public static boolean isSystemRoot() {
        boolean isRoot = false;
        try {
            isRoot = (new File("/system/bin/su").exists())
                    || (new File("/system/xbin/su").exists());
            Log.d("TAG", "isRoot  = " + isRoot);
        } catch (Exception e) {

        }
        return isRoot;
    }

    public static String getHostIP(Context activity) {

        String hostIp = null;
        try {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            InetAddress ia = null;
            while (nis.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                while (ias.hasMoreElements()) {
                    ia = ias.nextElement();
                    if (ia instanceof Inet6Address) {
                        continue;// skip ipv6
                    }
                    String ip = ia.getHostAddress();
                    if (!"127.0.0.1".equals(ip)) {
                        hostIp = ia.getHostAddress();
                        break;
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return hostIp;
    }

    /**
     * 返回用户手机运营商标识
     */
    public static String getProvidersName(Context context) {
        String ProvidersName = null;
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        @SuppressLint("MissingPermission") String IMSI = telephonyManager.getSubscriberId(); // 返回唯一的用户ID;就是这张卡的编号神马的
        if (IMSI == null)
            return "";//unkwon
        // IMSI号前面3位460是国家，紧接着后面2位00 02是中国移动，01是中国联通，03是中国电信。其中
        if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
            ProvidersName = "03";//中国移动
        } else if (IMSI.startsWith("46001")) {
            ProvidersName = "02";//中国联通
        } else if (IMSI.startsWith("46003")) {
            ProvidersName = "01";//中国电信
        }
        return ProvidersName;
    }

    /**
     * 网络类型判断
     */
    public static String getNetworkType(Context context) {
        String strNetworkType = NET_UNKNOWN;
        @SuppressLint("MissingPermission") NetworkInfo networkInfo = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected()) {
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                strNetworkType = NET_WIFI;
            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                String _strSubTypeName = networkInfo.getSubtypeName();
                // TD-SCDMA networkType is 17
                int networkType = networkInfo.getSubtype();
                switch (networkType) {
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                    case TelephonyManager.NETWORK_TYPE_IDEN: // api<8 : replace by
                        strNetworkType = NET_2G;
                        break;
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_B: // api<9 : replace by 14
                    case TelephonyManager.NETWORK_TYPE_EHRPD: // api<11 : replace by 12
                    case TelephonyManager.NETWORK_TYPE_HSPAP: // api<13 : replace by 15
                        strNetworkType = NET_3G;
                        break;
                    case TelephonyManager.NETWORK_TYPE_LTE: // api<11 : replace by 13
                        strNetworkType = NET_4G;
                        break;
                    default:
                        // http://baike.baidu.com/item/TD-SCDMA 中国移动 联通 电信 三种3G制式
                        if (_strSubTypeName.equalsIgnoreCase("TD-SCDMA") || _strSubTypeName.equalsIgnoreCase("WCDMA")
                                || _strSubTypeName.equalsIgnoreCase("CDMA2000")) {
                            strNetworkType = NET_3G;
                        } else {
                            strNetworkType = _strSubTypeName;
                        }
                        break;
                }
            }
        }
        return strNetworkType;
    }

    /**
     * 获取当前手机系统版本号
     *
     * @return 系统版本号
     */
    public static String getSystemVersion() {
        return Build.VERSION.RELEASE;
    }

    /**
     * 获取手机型号
     *
     * @return 手机型号
     */
    public static String getSystemModel() {
        return Build.MODEL;
    }

    /**
     * 判断当前设备是手机还是平板，代码来自 Google I/O App for Android
     *
     * @param context
     * @return 平板返回 True，手机返回 False
     */
    public static boolean isPad(Context context) {
        return (context.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
    }

    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */
    public static String getDeviceBrand() {
        return Build.BRAND;
    }

    /**
     * 获取手机当前sdk
     *
     * @return
     */
    public static String getDeviceSdk() {
        return Build.VERSION.SDK;
    }


    /**
     * 集合用逗号分开
     *
     * @param list
     * @return
     */
    public static String listToString1(List<String> list) {
        StringBuilder sb = new StringBuilder();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (i < list.size() - 1) {
                    sb.append(list.get(i) + "-");
                } else {
                    sb.append(list.get(i));
                }
            }
        }
        return sb.toString();
    }


    /**
     * 获取拼接的app信息
     *
     * @return
     */
    public static String getInfo() {
        ArrayList<String> strings = new ArrayList<>();
        strings.add(getSystemModel());
        strings.add(getAppVersion(GlobalApp.getAppContext()));
        strings.add(getDeviceBrand());
        strings.add(getSystemModel());
        strings.add(getDeviceSdk());
        strings.add(getSystemVersion());
        strings.add("android");
        return listToString1(strings);
    }


    /**
     * 这里获得deviceid  并不是imei   因为获取imei 需要 read_phone_state的权限，如果用户不允许的 就获取不到这个参数
     * 用build 获取手机信息拼接起来（有的人会想 如果所有两台手机参数都一样的话，这个参数不唯一的，这中情况有可能有，但是千万分之一的，可以不考虑的）
     *
     * @return
     */
    public static String getInfoDeviceID() {
        String deviceID = "";
        try {
            //一共13位  如果位数不够可以继续添加其他信息
            deviceID = "35" + Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

                    Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

                    Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

                    Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

                    Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

                    Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

                    Build.USER.length() % 10;
        } catch (Exception e) {
            return "";
        }
        return deviceID;
    }


    /**
     * 比较字符串资源版本号算法。
     * <pre>当同一个位置的时候出现数字和字母进行比较的时候我们默认字母号高于数字号。</pre>
     * <p>
     * 时间复杂度o(n)^2
     *
     * @param opt1 string 1
     * @param opt2 string 2
     * @return 当两个字符串相等的时候返回为0 ，当字符串1大于字符串2的时候返回1。
     * 当字符串1小于字符串2的时候返回为-1
     */
    public static int compareVersion(@NotNull String opt1, @NotNull String opt2) {
        if (opt1.hashCode() == opt2.hashCode()) {
            return 0;
        }
        String[] array1 = opt1.split("\\.");
        String[] array2 = opt2.split("\\.");
        int length = array1.length > array2.length ? array2.length : array1.length;
        for (int len = 0; len < length; len++) {
            if (checkNum(array1[len]) && checkNum(array2[len])) {
                int result = Integer.parseInt(array1[len]) - Integer.parseInt(array2[len]);
                if (result == 0) continue;
                return result > 0 ? 1 : -1;
            } else {
                String[] temp1 = subSplit(array1[len]);
                String[] temp2 = subSplit(array2[len]);
                int subLen = temp1.length > temp2.length ? temp2.length : temp1.length;
                for (int i = 0; i < subLen; i++) {
                    boolean check1 = checkNum(temp1[i]);
                    boolean check2 = checkNum(temp2[i]);
                    if (check1 && check2) {
                        int result = Integer.parseInt(temp1[i]) - Integer.parseInt(temp2[i]);
                        if (result == 0) continue;
                        return result > 0 ? 1 : -1;

                    } else if (!check1 && !check2) {//纯单个字母比较
                        if (temp1[i].equals(temp2[i])) continue;
                        return temp1[i].compareTo(temp2[i]);
                    }
                    //数字和字符混合比较
                    if (check1) return -1;
                    if (check2) return 1;
                }
                if (temp1.length != temp2.length)
                    return temp1.length > temp2.length ? 1 : -1;
            }
        }
        if (array1.length != array2.length)
            return array1.length > array2.length ? 1 : -1;
        return 0;
    }


    private static boolean checkNum(String str) {
        Pattern pattern = Pattern.compile("-?[0-9]+\\.?[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }


    private static String[] subSplit(String str) {
        StringBuilder number = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                number.append("|");
                number.append(str.charAt(i));
                number.append("|");
            } else {
                number.append(str.charAt(i));
            }
        }
        return number.toString().split("\\|+");
    }


    /**
     * 检查手机上是否安装了指定的软件
     *
     * @param context
     * @param packageName：应用包名 com.yuesheng.chat.sk  com.tencent.mm（微信）
     * @return
     */
    public static boolean isAvilible(Context context, String packageName) {
        //获取packagemanager
        final PackageManager packageManager = context.getPackageManager();
        //获取所有已安装程序的包信息
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        //用于存储所有已安装程序的包名
        List<String> packageNames = new ArrayList<String>();
        //从pinfo中将包名字逐一取出，压入pName list中
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                String packName = packageInfos.get(i).packageName;
                packageNames.add(packName);
            }
        }
        //判断packageNames中是否有目标程序的包名，有TRUE，没有FALSE
        return packageNames.contains(packageName);
    }


}
